package wymiana.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.annotations.Type;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
@Table(name = "users")
public class User extends BaseEntity implements UserDetails {

	private static final long serialVersionUID = 4907213777345060198L;

	public final static int USERNAME_LENGTH = 255;
	public final static int ROLE_LENGTH = 16;
	public final static int PASSWORD_LENGTH = 255;
	public final static int USERTHING_LENGTH = 255;

	@Id
	@Column(length = 255, updatable = false)
	private String username;

	@Column(length = 255, nullable = false)
	private String password;

	@Type(type = "org.hibernate.type.NumericBooleanType")
	@Column(nullable = false)
	private Boolean enabled;

	@Type(type = "org.hibernate.type.NumericBooleanType")
	@Column(nullable = false)
	private Boolean credentialsNonExpired;

	@Type(type = "org.hibernate.type.NumericBooleanType")
	@Column(nullable = false)
	private Boolean accountNonLocked;

	@Type(type = "org.hibernate.type.NumericBooleanType")
	@Column(nullable = false)
	private Boolean accountNonExpired;

	@Type(type = "org.hibernate.type.NumericBooleanType")
	@Column(nullable = false)
	private Boolean active;

	@Column(length = 255, nullable = false)
	private String name;

	@Column(length = 255, nullable = false)
	private String secondName;

	@Column(length = 255, nullable = false)
	private String email;

	@Column(nullable = false)
	private Integer phone;

	@Column(nullable = false)
	@Temporal(TemporalType.TIMESTAMP)
	private Date dateOfBirth;

	@OneToMany(cascade = { javax.persistence.CascadeType.ALL }, mappedBy = "user")
	private List<Photo> photos;

	@OneToMany(fetch = FetchType.EAGER, mappedBy = "username")
	@OnDelete(action = OnDeleteAction.NO_ACTION)
	private Collection<Authorities> authorities;
	
	@ManyToMany(fetch = FetchType.LAZY, mappedBy = "users")
	private List<DGroup> groups;

	public User() {
	}

	public User(String username, String password, Boolean enabled, Boolean active, Boolean credentialsNonExpired,
			Boolean accountNonLocked, Boolean accountNonExpired) {
		this.username = username;
		this.enabled = enabled;
		this.active = active;
		this.credentialsNonExpired = credentialsNonExpired;
		this.accountNonExpired = accountNonExpired;
		this.accountNonLocked = accountNonLocked;
		this.password = password;
	}

	public User(String username, String password, Boolean enabled, Boolean active, Boolean credentialsNonExpired,
			Boolean accountNonLocked, Boolean accountNonExpired, String name, String secondName, String email,
			Integer phone, Date dateOfBirth) {
		this(username, password, enabled, active, credentialsNonExpired, accountNonLocked, accountNonExpired);

		this.name = name;
		this.secondName = secondName;
		this.email = email;
		this.phone = phone;
		this.dateOfBirth = dateOfBirth;
	}

	public Boolean isActive() {
		return this.active;
	}

	public void setActive(Boolean active) {
		this.active = active;
	}

	public String getPassword() {
		return this.password;
	}

	public String getUsername() {
		return this.username;
	}

	public boolean isAccountNonExpired() {
		return this.accountNonExpired.booleanValue();
	}

	public boolean isAccountNonLocked() {
		return this.accountNonLocked.booleanValue();
	}

	public boolean isCredentialsNonExpired() {
		return this.credentialsNonExpired.booleanValue();
	}

	public boolean isEnabled() {
		return this.enabled.booleanValue();
	}

	public Collection<GrantedAuthority> getAuthorities() {
		List auth = new ArrayList();
		for (Authorities string : this.authorities) {
			auth.add(new GrantedAuthorityImpl(string.getAuthority()));
		}
		return auth;
	}

	public List<String> getPermissions() {
		List permision = new ArrayList();
		for (Authorities string : this.authorities) {
			permision.add(string.getAuthority());
		}
		return permision;
	}

	public Boolean getEnabled() {
		return this.enabled;
	}

	public void setEnabled(Boolean enabled) {
		this.enabled = enabled;
	}

	public Boolean getCredentialsNonExpired() {
		return this.credentialsNonExpired;
	}

	public void setCredentialsNonExpired(Boolean credentialsNonExpired) {
		this.credentialsNonExpired = credentialsNonExpired;
	}

	public Boolean getAccountNonLocked() {
		return this.accountNonLocked;
	}

	public void setAccountNonLocked(Boolean accountNonLocked) {
		this.accountNonLocked = accountNonLocked;
	}

	public Boolean getAccountNonExpired() {
		return this.accountNonExpired;
	}

	public void setAccountNonExpired(Boolean accountNonExpired) {
		this.accountNonExpired = accountNonExpired;
	}

	public void setAuthorities(Collection<Authorities> authorities) {
		this.authorities = authorities;
	}

	public Boolean getActive() {
		return this.active;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getName() {
		return this.name;
	}

	public String getSecondName() {
		return this.secondName;
	}

	public String getEmail() {
		return this.email;
	}

	public Integer getPhone() {
		return this.phone;
	}

	public Date getDateOfBirth() {
		return this.dateOfBirth;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setSecondName(String secondName) {
		this.secondName = secondName;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setPhone(Integer phone) {
		this.phone = phone;
	}

	public void setDateOfBirth(Date dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public boolean isNormalUser() {
		if (authorities != null) {
			for (Authorities a : authorities) {
				if (a.getAuthority().equals("ROLE_ADMIN")) {
					return false;
				}
			}
		}
		return true;
	}

	public List<Photo> getPhotos() {
		return photos;
	}

	public void setPhotos(List<Photo> photos) {
		this.photos = photos;
	}

	public List<DGroup> getGroups() {
		return groups;
	}

	public void setGroups(List<DGroup> groups) {
		this.groups = groups;
	}

}
